import { createOssUploadToken } from '@/api/file';
import { to } from '@/utils/await-to';
import { Message } from 'view-ui-plus';
import CryptoJS from 'crypto-js';
import OSS from 'ali-oss';

/**
 * 获取上传图片token
 */
export const fetchOssUploadToken = async (): Promise<{
  accessKeyId: string;
  accessKeySecret: string;
  bucket: string;
  domain: string;
  region: string;
  stsToken: string;
}> => {
  return new Promise((resolve, reject) => {
    async function exec() {
      const [err, data] = await to(createOssUploadToken(), null);
      if (err) {
        Message.error(err?.msg || '获取上传文件token失败');
        reject(err?.msg || '获取上传文件token失败');
        return;
      }
      resolve(data);
    }
    exec();
  });
};

/**
 * 上传图片
 */
export const uploadFile = async (file: File | Blob) => {
  const [err, data] = await to(fetchOssUploadToken(), null);

  if (err || !data) return null;
  console.log(data);
  const { accessKeyId, accessKeySecret, bucket, domain, region, stsToken } = data?.data?.data || {};

  if (!accessKeyId) return null;

  try {
    const client = new OSS({
      accessKeyId,
      accessKeySecret,
      bucket,
      region,
      stsToken,
      domain,
    });

    const result = await client.put(generateFileName(file), file, {
      process: (p: number) => {
        console.log(Math.floor(p * 100));
      },
    });

    console.log(result, 'result');
    return result?.url || '';
  } catch (error) {
    console.log(error);
    return '';
  }
};

/**
 * 将Base64字符串转换为File对象
 * @param {string} base64String - 图片的Base64字符串（包含data:image前缀）
 * @param {string} filename - 文件名（可选，默认是image.png）
 * @returns {File} File对象
 */
export function base64ToFile(base64String: string, filename = 'image.png') {
  // 分离Base64数据和类型信息
  const arr = base64String.split(',');
  const mime = arr[0].match(/:(.*?);/)[1]; // 获取MIME类型（如image/png）
  const bstr = atob(arr[1]); // 解码Base64数据

  // 将二进制字符串转换为Uint8Array
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }

  // 创建Blob对象并转换为File对象
  return new File([u8arr], filename, { type: mime });
}

/**
 * 生成唯一文件名
 */
export const generateFileName = (file: File | Blob) => {
  const timestamp = new Date().getTime();
  const randomString = CryptoJS.lib.WordArray.random(8).toString();

  return `app/${timestamp}_${randomString}.${file.name.split('.').pop()}`;
};
